#pragma once
#include "ManagedCryptBlob.h"

namespace Safe
{

	/// <summary>
	/// Creates the ASN structure for an RFC3161 timestamp request
	/// </summary>
	public ref class TimestampRequest
	{
	public:
		/// <summary>
		/// Creates a new RFC3161 request using the given hash
		/// </summary>
		/// <param name='hash'>The hash to send to the timestamp server</param>
		/// <param name='hashAlg'>The hash algorithm</param>
		TimestampRequest(ManagedCryptBlob^ hash, System::String^ hashAlg );

		/// <summary>
		/// Gets the hash used in the timestamp request.  This property
		/// is read-only.
		/// </summary>
		property ManagedCryptBlob^ Hash { 
			ManagedCryptBlob^ get() { return m_hash; }
		}

		/// <summary>
		/// Gets the binary HTTP RFC3161 request.  This property is read-only.
		/// </summary>
		property ManagedCryptBlob^ Request { 
			ManagedCryptBlob^ get() { return m_request; }
		}
		
	private:
		/// <summary>
		/// The hash data used as the basis for the timestamp request
		/// </summary>
		ManagedCryptBlob^ m_hash;

		/// <summary>
		/// The binary HTTP RFC3161 request
		/// </summary>
		ManagedCryptBlob^ m_request;

	
		/// <summary>
		/// Destructor
		/// </summary>
		virtual ~TimestampRequest(void);

		/// <summary>
		/// Creates the outer sequence of the timestamp request
		/// </summary>
		/// <param name='version'>The timestamp request version</param>
		/// <param name='hashOid'>The algorithm identifier of the hash algorithm</param>
		/// <param name='reqServerCert'>Whether or not the server should include the
		/// timestamp server certificate in the response</param>		
		/// <returns>An error code from errors.h</returns>
		int CreateRequest(int version, System::String^ hashOid, bool reqServerCert);
		
		/// <summary>
		/// Creates the outer sequence of the timestamp request
		/// </summary>
		/// <param name='version'>The timestamp request version</param>
		/// <param name='hashOid'>The algorithm identifier of the hash algorithm</param>
		/// <param name='reqServerCert'>Whether or not the server should include the
		/// timestamp server certificate in the response</param>		
		/// <returns>An error code from errors.h</returns>
		int CreateRequest(int version, const char *hashOid, bool reqServerCert);

		/// <summary>
		/// Creates the inner sequence of the timestamp request.  This function allocates
		/// memory in the CRYPT_DER_BLOB which must be freed using FreeMem.  
		/// See GemsecUtilities.h.
		/// </summary>
		/// <param name='hashOid'>The algorithm identifier of the hash algorithm</param>
		/// <param name='reqServerCert'>Destination buffer to receive the encoded
		/// inner sequence</param>		
		/// <returns>An error code from errors.h</returns>
		int CreateRequestInnerSeq(const char *hashOid, CRYPT_DER_BLOB &encoded);
		
		/// <summary>
		/// DER Encodes a boolean value.  This function allocates memory in the 
		/// CRYPT_DER_BLOB which must be freed using FreeMem.  See GemsecUtilities.h.
		/// </summary>
		/// <param name='value'>The boolean value to encode</param>
		/// <param name='encoded'>Destination buffer to receive the encoded ASN object</param>
		/// <returns>An error code from errors.h</returns>
		int EncodeBoolean(bool value, CRYPT_DER_BLOB &encoded);
	};
}